﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace NobleTech.Products.CreatureKingdom.WPFClient.Controls
{
    public class MapSelector : Control
    {
        public double MapPositionX
        {
            get { return (double)GetValue(MapPositionXProperty); }
            set { SetValue(MapPositionXProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MapPositionX.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MapPositionXProperty =
            DependencyProperty.Register("MapPositionX", typeof(double), typeof(MapSelector),new PropertyMetadata(new PropertyChangedCallback(OnRecalculate)));



        public double MapPositionY
        {
            get { return (double)GetValue(MapPositionYProperty); }
            set { SetValue(MapPositionYProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MapPositionY.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MapPositionYProperty =
            DependencyProperty.Register("MapPositionY", typeof(double), typeof(MapSelector), new PropertyMetadata(new PropertyChangedCallback(OnRecalculate)));

        public double MapZoom
        {
            get { return (double)GetValue(MapZoomProperty); }
            set { SetValue(MapZoomProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MapZoom.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MapZoomProperty =
            DependencyProperty.Register("MapZoom", typeof(double), typeof(MapSelector), new UIPropertyMetadata(new PropertyChangedCallback(OnRecalculate)));

        public double MapSizeX
        {
            get { return (double)GetValue(MapSizeXProperty); }
            set { SetValue(MapSizeXProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MapSizeX.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MapSizeXProperty =
            DependencyProperty.Register("MapSizeX", typeof(double), typeof(MapSelector), new UIPropertyMetadata(new PropertyChangedCallback(OnRecalculate)));




        public double MapSizeY
        {
            get { return (double)GetValue(MapSizeYProperty); }
            set { SetValue(MapSizeYProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MapSizeY.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MapSizeYProperty =
            DependencyProperty.Register("MapSizeY", typeof(double), typeof(MapSelector), new UIPropertyMetadata(new PropertyChangedCallback(OnRecalculate)));




        public double MapPixelSizeX
        {
            get { return (double)GetValue(MapPixelSizeXProperty); }
            set { SetValue(MapPixelSizeXProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MapPixelSizeX.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MapPixelSizeXProperty =
            DependencyProperty.Register("MapPixelSizeX", typeof(double), typeof(MapSelector), new UIPropertyMetadata(new PropertyChangedCallback(OnRecalculate)));


        public double MapPixelSizeY
        {
            get { return (double)GetValue(MapPixelSizeYProperty); }
            set { SetValue(MapPixelSizeYProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MapPixelSizeX.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MapPixelSizeYProperty =
            DependencyProperty.Register("MapPixelSizeY", typeof(double), typeof(MapSelector), new UIPropertyMetadata(new PropertyChangedCallback(OnRecalculate)));





        private static void OnRecalculate(DependencyObject Sender, DependencyPropertyChangedEventArgs Args)
        {

            if (Sender as MapSelector != null)
                (Sender as MapSelector).Recalculate();
        }

        private void Recalculate()
        {
            Rectangle Selector = this.GetTemplateChild("PART_Selector") as Rectangle;
            if (Selector == null)
                return;

            TranslateTransform SelectorTranslate = new TranslateTransform();
            SelectorTranslate.X= (MapPositionX-MapPixelSizeX/2/MapZoom) / MapSizeX * ActualWidth;
            SelectorTranslate.Y = (MapPositionY - MapPixelSizeY / 2 / MapZoom) / MapSizeY * ActualHeight;
            Selector.RenderTransform = SelectorTranslate;

            Selector.Width = MapPixelSizeX / MapZoom / MapSizeX * ActualWidth;
            Selector.Height = MapPixelSizeY / MapZoom / MapSizeY * ActualHeight;
        }


        static MapSelector()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MapSelector), new FrameworkPropertyMetadata(typeof(MapSelector)));
        }


        public MapSelector()
        {
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            Rectangle Selector = this.GetTemplateChild("PART_Selector") as Rectangle;
            if (Selector == null)
                return;
            Selector.MouseDown += new MouseButtonEventHandler(Selector_MouseDown);
            Selector.MouseUp += new MouseButtonEventHandler(Selector_MouseUp);
            Selector.MouseMove += new MouseEventHandler(Selector_MouseMove);
        }

        double InitialPositionX, InitialPositionY;
        void Selector_MouseMove(object sender, MouseEventArgs e)
        {
            Rectangle Selector = this.GetTemplateChild("PART_Selector") as Rectangle;
            if (Mouse.Captured == Selector)
            {
                MapPositionX += (e.GetPosition(this).X - InitialPositionX) * MapSizeX / this.ActualWidth;
                MapPositionY += (e.GetPosition(this).Y - InitialPositionY) * MapSizeY / this.ActualHeight;

                if (MapPositionX < MapPixelSizeX / 2 / MapZoom)
                    MapPositionX = MapPixelSizeX / 2 / MapZoom;
                if (MapPositionY < MapPixelSizeY / 2 / MapZoom)
                    MapPositionY = MapPixelSizeY / 2 / MapZoom;
                if (MapPositionX > (MapSizeX - MapPixelSizeX / 2 / MapZoom))
                    MapPositionX = (MapSizeX - MapPixelSizeX / 2 / MapZoom);
                if (MapPositionY > (MapSizeY - MapPixelSizeY / 2 / MapZoom))
                    MapPositionY = (MapSizeY - MapPixelSizeY / 2 / MapZoom);

                InitialPositionX = e.GetPosition(this).X;
                InitialPositionY = e.GetPosition(this).Y;
            }
         }

        void Selector_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Rectangle Selector = this.GetTemplateChild("PART_Selector") as Rectangle;
            Mouse.Capture(Selector, CaptureMode.None);
        }

        void Selector_MouseDown(object sender, MouseButtonEventArgs e)
        {
            
            Rectangle Selector = this.GetTemplateChild("PART_Selector") as Rectangle;
            InitialPositionX = e.GetPosition(this).X;
            InitialPositionY = e.GetPosition(this).Y;
            Mouse.Capture(Selector, CaptureMode.Element);
       
        }
    }
}
